package tankgame.tankgame3;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Vector;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine.Info;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

import sun.audio.AudioData;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import sun.audio.ContinuousAudioDataStream;

/**
 * 
 * @author wuhuiwen 播放音频文件，产生音效
 */
public class MusicPlay {
	private AudioStream as; // 单次播放声音用
	ContinuousAudioDataStream cas;// 循环播放声音
	// 构造函数

	public MusicPlay(String fileName) {
		try {
			// 打开一个声音文件流作为输入
			try {
				as = new AudioStream(AudioSystem.getAudioInputStream(new File(fileName)));
			} catch (UnsupportedAudioFileException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// 一次播放 开始
	public void start() {
		if (as == null) {
			System.out.println("AudioStream object is not created!");
			return;
		} else {
			AudioPlayer.player.start(as);
		}
	}

	// 一次播放 停止
	public void stop() {
		if (as == null) {
			System.out.println("AudioStream object is not created!");
			return;
		} else {
			AudioPlayer.player.stop(as);
		}
	}

	// 循环播放 开始
	public void continuousStart() {
		// Create AudioData source.
		AudioData data = null;
		try {
			data = as.getData();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// Create ContinuousAudioDataStream.
		cas = new ContinuousAudioDataStream(data);

		// Play audio.
		AudioPlayer.player.start(cas);
	}

	// 循环播放 停止
	public void continuousStop() {
		if (cas != null) {
			AudioPlayer.player.stop(cas);
		}
	}

	public static void main(String[] args) {
		MusicPlay myMusicPlay = new MusicPlay("D:\\python\\workspace\\pycharm\\12声音\\GameBGMs\\坦克大战.wav");
		myMusicPlay.start();// 播放一次
		// myMusicPlay.stop();// 停止
		// myMusicPlay.continuousStart();// 循环播放
		// myMusicPlay.continuousStop();// 停止
	}
}

class AudioPlay extends Thread {

	String fileName;

	public AudioPlay(String fileName) {
		super();
		this.fileName = fileName;
	}

	@Override
	public void run() {
		File f = new File(fileName);
		AudioInputStream ais = null;
		SourceDataLine auline = null;
		try {
			ais = AudioSystem.getAudioInputStream(f);
			AudioFormat af = ais.getFormat();
			Info info = new Info(SourceDataLine.class, af);
			auline = (SourceDataLine) AudioSystem.getLine(info);
			auline.open(af);
			auline.start();
			int size = 0;
			byte[] datas = new byte[1024];
			while ((size = ais.read(datas, 0, datas.length)) != -1) {
				auline.write(datas, 0, size);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			auline.drain();
			auline.close();
		}

	}
}

class Record {
	static int enemyNum = 20;
	static int myLife = 3;
	static int dieEnemyNum = 0;
	static Vector<Enemy> enemies = new Vector<Enemy>();

	public static void reduceNum(Tank t) {
		if (t instanceof Enemy) {
			enemyNum--;
			dieEnemyNum++;
		} else {
			myLife--;
		}
	}

	public static void saveRecord() {
		FileWriter fw = null;
		BufferedWriter bw = null;
		try {
			fw = new FileWriter("d:/record1.txt");
			bw = new BufferedWriter(fw);
			bw.write(dieEnemyNum + "\r\n");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				bw.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				fw.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public static void readRecord() {
		FileReader fr = null;
		BufferedReader br = null;
		File file = new File("d:/record1.txt");
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			try {
				fr = new FileReader(file);
				br = new BufferedReader(fr);
				String s = br.readLine();
				dieEnemyNum = Integer.parseInt(s);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				try {
					fr.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}

	public static void saveGame() {
		FileWriter fw = null;
		BufferedWriter bw = null;
		try {
			fw = new FileWriter("d:/record1.txt");
			bw = new BufferedWriter(fw);
			bw.write(dieEnemyNum + "\r\n");
			for (int i = 0; i < enemies.size(); i++) {
				if (enemies.get(i).isLive) {
					bw.write(enemies.get(i).x + "_" + enemies.get(i).y + "_" + enemies.get(i).direct + "\r\n");
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				bw.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				fw.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public static void continueGame() {
		FileReader fr = null;
		BufferedReader br = null;
		File file = new File("d:/record1.txt");
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			try {
				fr = new FileReader(file);
				br = new BufferedReader(fr);
				String s = br.readLine();
				dieEnemyNum = Integer.parseInt(s);
				while ((s = br.readLine()) != null) {
					String[] dis = s.split("_");
					enemies.add(new Enemy(Integer.parseInt(dis[0]), Integer.parseInt(dis[1]), Integer.parseInt(dis[2]),
							1, Color.BLUE));
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				try {
					fr.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}
}

class Bomb {
	int x, y;
	int life = 9;

	public Bomb(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public void lifeDown() {
		if (life > 0) {
			life--;
		}
	}
}

class Shot implements Runnable {
	int x;
	int y;
	int direct;
	int speed;// 速度
	boolean isLive = true;

	public Shot(int x, int y, int direct) {
		this.x = x;
		this.y = y;
		this.direct = direct;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	@Override
	public String toString() {
		return "Shot [x=" + x + ", y=" + y + ", direct=" + direct + ", speed=" + speed + ", isLive=" + isLive + "]";
	}

	@Override
	public void run() {
		while (true) {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			switch (direct) {
			case 0:
				y -= speed;
				break;
			case 1:
				y += speed;
				break;
			case 2:
				x -= speed;
				break;
			case 3:
				x += speed;
				break;
			}
			if (x < 0 || x > 400 || y < 0 || y > 300) {
				isLive = false;
				break;
			}
		}

	}

}

class Tank {
	int x = 0;// 横坐标
	int y = 0;// 纵坐标
	int direct;// 0表示上，1表示下，2表示左，3表示右
	int speed;// 速度
	Color color;// 颜色
	Vector<Shot> shots = new Vector<Shot>();// 子弹
	Shot shot;
	boolean isLive = true;

	public void shotEnemy() {
		switch (direct) {
		case 0:
			shot = new Shot(x + 10, y, 0);
			break;
		case 1:
			shot = new Shot(x + 10, y + 30, 1);
			break;
		case 2:
			shot = new Shot(x, y + 10, 2);
			break;
		case 3:
			shot = new Shot(x + 30, y + 10, 3);
			break;
		}
		shots.add(shot);
		shot.setSpeed(3);
		new Thread(shot).start();

	}

	public Tank(int x, int y, int direct, int speed, Color color) {
		super();
		this.x = x;
		this.y = y;
		this.direct = direct;
		this.speed = speed;
		this.color = color;
	}

	public void moveUp() {
		y -= speed;
	}

	public void moveDown() {
		y += speed;
	}

	public void moveLeft() {
		x -= speed;
	}

	public void moveRight() {
		x += speed;
	}

	@Override
	public String toString() {
		return "Tank [x=" + x + ", y=" + y + ", direct=" + direct + ", speed=" + speed + ", shots=" + shots
				+ ", isLive=" + isLive + "]";
	}
}

class Hero extends Tank {
	public Hero(int x, int y, int direct, int speed, Color color) {
		super(x, y, direct, speed, color);
	}
}

class Enemy extends Tank implements Runnable {
	Vector<Enemy> enemies = new Vector<Enemy>();// 敌方坦克

	public void setEnemies(Vector<Enemy> enemies) {
		this.enemies = enemies;
	}

	public Enemy(int x, int y, int direct, int speed, Color color) {
		super(x, y, direct, speed, color);
	}

	public boolean isTouchOthers() {// 与其他坦克碰撞检测
		boolean isTouch = false;
		for (int i = 0; i < enemies.size(); i++) {
			Enemy e = enemies.get(i);
			if (e != this) {
				switch (direct) {
				case 0:// 向上
					if (e.direct == 0 || e.direct == 1) {// 其他坦克向上或向下
						// 上左点
						if (x >= e.x && x <= e.x + 20 && y >= e.y && y <= e.y + 30) {
							return true;
						}
						// 上右点
						if (x + 20 >= e.x && x + 20 <= e.x + 20 && y >= e.y && y <= e.y + 30) {
							return true;
						}
					}
					if (e.direct == 2 || e.direct == 3) {// 其他坦克向左或向右
						// 上左点
						if (x >= e.x && x <= e.x + 30 && y >= e.y && y <= e.y + 20) {
							return true;
						}
						// 上右点
						if (x + 20 >= e.x && x + 20 <= e.x + 30 && y >= e.y && y <= e.y + 20) {
							return true;
						}
					}
					break;
				case 1:// 向下
					if (e.direct == 0 || e.direct == 1) {// 其他坦克向上或向下
						// 下左点
						if (x >= e.x && x <= e.x + 20 && y + 30 >= e.y && y + 30 <= e.y + 30) {
							return true;
						}
						// 下右点
						if (x + 20 >= e.x && x + 20 <= e.x + 20 && y + 30 >= e.y && y + 30 <= e.y + 30) {
							return true;
						}
					}
					if (e.direct == 2 || e.direct == 3) {// 其他坦克向左或向右
						// 下左点
						if (x >= e.x && x <= e.x + 30 && y + 30 >= e.y && y + 30 <= e.y + 20) {
							return true;
						}
						// 下右点
						if (x + 20 >= e.x && x + 20 <= e.x + 30 && y + 30 >= e.y && y + 30 <= e.y + 20) {
							return true;
						}
					}
					break;
				case 2:// 向左
					if (e.direct == 0 || e.direct == 1) {// 其他坦克向上或向下
						// 左上点
						if (x >= e.x && x <= e.x + 20 && y >= e.y && y <= e.y + 30) {
							return true;
						}
						// 左下点
						if (x >= e.x && x <= e.x + 20 && y + 20 >= e.y && y + 20 <= e.y + 30) {
							return true;
						}
					}
					if (e.direct == 2 || e.direct == 3) {// 其他坦克向左或向右
						// 左上点
						if (x >= e.x && x <= e.x + 30 && y >= e.y && y <= e.y + 20) {
							return true;
						}
						// 左下点
						if (x >= e.x && x <= e.x + 30 && y + 20 >= e.y && y + 20 <= e.y + 20) {
							return true;
						}
					}
					break;
				case 3:// 向右
					if (e.direct == 0 || e.direct == 1) {// 其他坦克向上或向下
						// 右上点
						if (x + 30 >= e.x && x + 30 <= e.x + 20 && y >= e.y && y <= e.y + 30) {
							return true;
						}
						// 右下点
						if (x + 30 >= e.x && x + 30 <= e.x + 20 && y + 20 >= e.y && y + 20 <= e.y + 30) {
							return true;
						}
					}
					if (e.direct == 2 || e.direct == 3) {// 其他坦克向左或向右
						// 右上点
						if (x + 30 >= e.x && x + 30 <= e.x + 30 && y >= e.y && y <= e.y + 20) {
							return true;
						}
						// 右上点
						if (x + 30 >= e.x && x + 30 <= e.x + 30 && y + 20 >= e.y && y + 20 <= e.y + 20) {
							return true;
						}
					}
					break;

				}
			}

		}
		return isTouch;

	}

	@Override
	public void run() {// 让坦克随机运行
		while (true) {
			switch (this.direct) {
			case 0:
				for (int i = 0; i < 30; i++) {
					if (y > 0 && !isTouchOthers()) {
						y -= speed;
					}
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				break;
			case 1:
				for (int i = 0; i < 30; i++) {
					if (y < 270 && !isTouchOthers()) {
						y += speed;
					}
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				break;
			case 2:
				for (int i = 0; i < 30; i++) {
					if (x > 0 && !isTouchOthers()) {
						x -= speed;
					}
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				break;
			case 3:
				for (int i = 0; i < 30; i++) {
					if (x < 370 && !isTouchOthers()) {
						x += speed;
					}
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				break;
			}
			// 让坦克随机产生一个方向
			direct = (int) (Math.random() * 4);
			if (isLive && shots.size() < 6) {
				shotEnemy();// 敌方发子弹
			} else {
				break;
			}

		}

	}

}